package com.dxx.cloud.admin.utils;

import com.dxx.cloud.admin.constant.CommonConst;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author duh
 * @create 2020/5/20 21:04
 * @email duh@elab-plus.com
 **/
public class LocalTimeUtils {

    private static Logger logger = LoggerFactory.getLogger(LocalTimeUtils.class);

    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss:SSS";
    public static final String HH_MM_SS = "HH:mm:ss";

    public static final String EMPTY_MS_END = ".0";

    private static final DateTimeFormatter YYYY_MM_DD_FORMATTER = DateTimeFormatter.ofPattern(YYYY_MM_DD);
    private static final DateTimeFormatter YYYY_MM_DD_HH_MM_SS_FORMATTER = DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS);
    private static final DateTimeFormatter YYYY_MM_DD_HH_MM_SS_SSS_FORMATTER = DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS_SSS);
    private static final DateTimeFormatter HH_MM_SS_FORMATTER = DateTimeFormatter.ofPattern(HH_MM_SS);

    /**
     * 数天后
     *
     * @param dayNumber
     * @return
     */
    public static LocalDate daysLater(Integer dayNumber) {
        final LocalDate now = LocalDate.now();
        return now.plusDays(dayNumber);
    }

    /**
     * 上一天
     *
     * @param dateStr
     * @return
     */
    public static LocalDate lastDay(String dateStr) {
        LocalDate lastDay = null;
        try {
            lastDay = LocalDate.parse(dateStr).minusDays(1);
        }catch (Exception e){
            logger.info("转换日期报错,"+e.getMessage());
        }finally {
            return lastDay;
        }

    }

    /**
     * 数小时后
     *
     * @param hourNumber
     * @return
     */
    public static LocalDateTime hoursLater(Integer hourNumber) {
        final LocalDateTime now = LocalDateTime.now();
        return now.plusHours(hourNumber);
    }

    /**
     * 数小时后
     * @param dateTimeStr
     * @param hourNumber
     * @return
     */
    public static String hoursLater(String dateTimeStr,Integer hourNumber) {
        String result = null;
        if(ObjectUtils.isNotEmpty(dateTimeStr)){
            LocalDateTime time = LocalDateTime.parse(dateTimeStr, YYYY_MM_DD_HH_MM_SS_FORMATTER);
            LocalDateTime timeLater = time.plusHours(hourNumber);
            result =  timeLater.format(YYYY_MM_DD_HH_MM_SS_FORMATTER);
        }
        return result;
    }

    /**
     * 转换成北京时间
     * @param date
     * @param timeArea
     */
    public static Date changeToBeijingTime(Date date, Integer timeArea) {
        if(null != date && !CommonConst.DEFAULT_TIME_AREA.equals(timeArea)){
            Integer areaDiff = CommonConst.DEFAULT_TIME_AREA - timeArea;
            LocalDateTime beiJingTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().plusHours(areaDiff);
            date = localDateTime2Date(beiJingTime);
        }
        return date;
    }
    /**
     * 一定时间后
     * @param timeNumber
     * @return
     */
    public static Date timeLater(Integer timeNumber,TemporalUnit unit) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime timeAfter = now.plus(timeNumber, unit);
        return Date.from(timeAfter.atZone(ZoneId.systemDefault()).toInstant());
    }
    /**
     * 转日期
     *
     * @param localDate
     * @return
     */
    public static Date localDate2Date(LocalDate localDate) {
        Date date = null;
        if (null != localDate) {
            ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
            date = Date.from(zonedDateTime.toInstant());
        }
        return date;
    }

    public static Date localDateTime2Date(LocalDateTime localDateTime) {
        Date date = null;
        if (null != localDateTime) {
            ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
            date = Date.from(zonedDateTime.toInstant());
        }
        return date;
    }


    /**
     * 移除空的毫秒
     *
     * @param dataStr
     * @return
     */
    public static String removeEmptyMsEnd(String dataStr) {
        if (ObjectUtils.isNotEmpty(dataStr)) {
            dataStr = dataStr.replace(EMPTY_MS_END, "");
        }
        return dataStr;
    }

    /**
     * 与当前日期差
     *
     * @param date
     * @return
     */
    public static Integer dateDiff(Date date) {
        if (null == date) {
            return null;
        }
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        return (int) LocalDate.now().until(localDate, ChronoUnit.DAYS);
    }

    /**
     * 与昨天日期差
     *
     * @param date
     * @return
     */
    public static Integer dateDiffYesterday(Date date) {
        if (null == date) {
            return null;
        }
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        return (int) LocalDate.now().minusDays(1).until(localDate, ChronoUnit.DAYS);
    }

    /**
     * 带毫秒的当前日期
     * @return
     */
    public static String currentTimeWithMs(){
        return YYYY_MM_DD_HH_MM_SS_SSS_FORMATTER.format(LocalDateTime.now());
    }


    public static Date stringToDate(String dateStr) {
        if (!StringUtils.hasText(dateStr)) {
            return null;
        }
        LocalDateTime dateTime = null;
        try {
            if (dateStr.length() == 19) {
                //1234-67-90 23:56:89
                return localDateTime2Date(LocalDateTime.parse(dateStr, YYYY_MM_DD_HH_MM_SS_FORMATTER));
            } else if (dateStr.length() == 10) {
                return localDate2Date(LocalDate.parse(dateStr, YYYY_MM_DD_FORMATTER));
            }
        } catch (Exception e) {
            logger.info("", e);
        }
        return null;
    }

    /**
     * 取date的日期
     * @param date
     * @return
     */
    public static LocalDate date2LocalDate(Date date) {
        if (null != date) {
            return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        } else {
            return null;
        }
    }


    /**
     * 两个日期之间的所有日期
     * @param beginDate
     * @param endDate
     * @return
     */
    public static List<String> dateAreaBetweenBeginAndEndDate(String beginDate, String endDate){
        List<String> dateList = new ArrayList<>();
        if(ObjectUtils.isEmpty(endDate) || ObjectUtils.isEmpty(beginDate)){
            return dateList;
        }
        LocalDate beginLocalDate = LocalTimeUtils.date2LocalDate(LocalTimeUtils.stringToDate(beginDate));
        LocalDate endLocalDate = LocalTimeUtils.date2LocalDate(LocalTimeUtils.stringToDate(endDate));
        assert beginLocalDate != null;
        assert endLocalDate != null;
        long diff = beginLocalDate.until(endLocalDate, ChronoUnit.DAYS);
        for (long i = 0; i <= diff; i++) {
            dateList.add(beginLocalDate.plusDays(i).toString());
        }
        return dateList;
    }

    public static Date parseDateWithFormat(String dateTimeStr,String format){
        if(null == dateTimeStr || dateTimeStr.isEmpty()){
            return null;
        }
        LocalDateTime parsedTime = LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(format));
        return Date.from(parsedTime.atZone(ZoneId.systemDefault()).toInstant());
    }
    public static void main(String[] args) {
//        System.out.println(daysLater(12));
//        System.out.println(localDate2Date(daysLater(12)));
//
//        System.out.println(removeEmptyMsEnd("2018-21-23 12:21:21.0"));

//        Date date = new Date();
//        System.out.println(dateDiffYesterday(date));
//        System.out.println(currentTimeWithMs());
//        Date date = new Date();
//        System.out.println(date2LocalDate(null));
//        System.out.println(lastDay("2020-05-01"));
//        System.out.println(dateAreaBetweenBeginAndEndDate("2020-05-01","2020-05-18"));
//        System.out.println(hoursLater("2020-05-01 00:11:12",1));
        System.out.println(parseDateWithFormat("20210202163446","yyyyMMddHHmmss"));
    }


}
